#include <stdio.h>
#include <string.h>

// 条件类型枚举
typedef enum {
    COND_FRONT_GT,  // 闸前水位大于
    COND_FRONT_LT,  // 闸前水位小于
    COND_REAR_LT,   // 闸后水位小于等于
    COND_REAR_GT,   // 闸后水位大于
    COND_PERIOD_EQ  // 时段等于
} ConditionType;

// 条件结构体
typedef struct {
    ConditionType type;
    float value;         // 比较值（水位或时段编码）
    const char* period;  // 时段字符串比较
} Condition;

// 规则结构体
typedef struct {
    Condition conditions[5]; // 最多支持5个条件组合
    int condition_count;
    int action_open;         // 动作：1=开启，0=关闭, 2=保持
} Rule;

// 闸门配置结构体
typedef struct {
    float front_high;    // 闸前高水位阈值
    float front_low;     // 闸前低水位阈值
    float rear_high;     // 闸后安全水位
    Rule rules[10];      // 最多支持10条规则
    int rule_count;      // 实际规则数量
} GateConfig;

// 闸门状态结构体
typedef struct {
    const GateConfig* config;  // 配置指针
    float front_water;         // 当前闸前水位
    float rear_water;          // 当前闸后水位
    const char* period;        // 当前时段
    int is_open;               // 当前闸门状态
} GateState;

/**
 * 检查单个条件是否满足
 * @param cond 条件指针
 * @param state 当前闸门状态
 * @return 满足返回1，否则返回0
 */
int check_condition(const Condition* cond, const GateState* state) {
    switch (cond->type) {
        case COND_FRONT_GT:
            return state->front_water > cond->value;
        case COND_FRONT_LT:
            return state->front_water < cond->value;
        case COND_REAR_LT:
            return state->rear_water <= cond->value;
        case COND_REAR_GT:
            return state->rear_water > cond->value;
        case COND_PERIOD_EQ:
            return strcmp(state->period, cond->period) == 0;
        default:
            return 0;
    }
}

/**
 * 评估所有规则并更新闸门状态
 * @param state 闸门状态指针
 */
void evaluate_rules(GateState* state) {
    // 遍历所有规则（按优先级顺序）
    for (int i = 0; i < state->config->rule_count; ++i) {
        const Rule* rule = &state->config->rules[i];
        int all_conditions_met = 1;
        
        // 检查规则的所有条件
        for (int j = 0; j < rule->condition_count; ++j) {
            if (!check_condition(&rule->conditions[j], state)) {
                all_conditions_met = 0; 
                break;  //不满足条件检查下一规则
            }
        }
        
        if (all_conditions_met) { 
            state->is_open = rule->action_open;
            return; // 执行首个匹配规则
        }
    }
}

/* 预定义配置实例 */

// 泄洪闸配置
const GateConfig flood_gate_config = {
    .front_high = 10.0f,
    .rear_high = 8.0f,
    .rules = {
        {   //放水
            .conditions = {
                {COND_REAR_LT, 8.0f, NULL},
                {COND_FRONT_GT, 10.0f ,NULL}
            },
            .condition_count = 2,
            .action_open = 1
        },
        {   //蓄水1
            .conditions = {
                {COND_FRONT_GT, 10.0f ,NULL},
                {COND_REAR_GT, 8.0f ,NULL}
            },
            .condition_count = 2,
            .action_open = 0
        },
        {   //蓄水2
            .conditions = {
                {COND_FRONT_LT, 10.0f ,NULL}
            },
            .condition_count = 1,
            .action_open = 0
        }
    },
    .rule_count = 3
};

// 进水闸配置
const GateConfig intake_gate_config = {
    .rear_high = 5.0f,
    .rules = {
        {   //放水
            .conditions = {{COND_REAR_LT, 5.0f, NULL}},
            .condition_count = 1,
            .action_open = 1
        },
        {   //蓄水
            .conditions = {{COND_REAR_GT, 5.0f, NULL}},
            .condition_count = 1,
            .action_open = 0
        }
    },
    .rule_count = 2
};

// 水库A配置
const GateConfig reservoir_A_config = {
    .front_high = 15.0f,
    .front_low = 5.0f,
    .rear_high = 10.0f,
    .rules = {
        {   //放水
            .conditions = {
                {COND_REAR_LT, 10.0f, NULL},
                {COND_FRONT_GT, 15.0f, NULL}
            },
            .condition_count = 2,
            .action_open = 1
        },
        {   //蓄水1
            .conditions = {
                {COND_REAR_GT, 10.0f, NULL},
                {COND_FRONT_GT, 15.0f, NULL}
            },
            .condition_count = 2,
            .action_open = 0
        },
        {   //蓄水2
            .conditions = {
                {COND_FRONT_LT, 5.0f, NULL}
            },
            .condition_count = 1,
            .action_open = 0
        },
        {   //保持
            .conditions = {
                {COND_FRONT_LT, 15.0f, NULL},
                {COND_FRONT_GT, 5.0f, NULL}
            },
            .condition_count = 2,
            .action_open = 2
        }
    },
    .rule_count = 4
};

// 水库B配置
const GateConfig reservoir_B_config = {
    .front_high = 20.0f,
    .rear_high = 12.0f,
    .rules = {
        {   //峰电放水
            .conditions = {
                {COND_REAR_LT, 12.0f, NULL},
                {COND_PERIOD_EQ, 0, "peak"}
            },
            .condition_count = 2,
            .action_open = 1
        },
        {   //峰电蓄水
            .conditions = {
                {COND_REAR_GT, 12.0f, NULL},
                {COND_PERIOD_EQ, 0, "peak"}
            },
            .condition_count = 2,
            .action_open = 0
        },
        {   // 谷电放水
            .conditions = {
                {COND_REAR_LT, 12.0f, NULL},
                {COND_PERIOD_EQ, 0, "offpeak"},
                {COND_FRONT_GT, 20.0f, NULL},
            },
            .condition_count = 3,
            .action_open = 1
        },
        {   //谷电蓄水
            .conditions = {
                {COND_PERIOD_EQ, 0, "offpeak"},
                {COND_FRONT_LT, 20.0f, NULL},
            },
            .condition_count = 2,
            .action_open = 0
        }
    },
    .rule_count = 4
};

int main() {
    // const GateConfig GateConfig_arr[4]={flood_gate_config,intake_gate_config,reservoir_A_config,reservoir_B_config};
    // int select=-1,time=-1;
    // float front_water=0.0f,rear_water=0.0f;
    // while(1)
    // {
    //     printf("请输入闸门类型(0为泄洪闸,1为进水闸,2为水库A,3为水库B:\n");
    //     scanf("%d",&select);
    //     printf("请输入闸前水位、闸后水位:\n");
    //     scanf("%f %f",&front_water,&rear_water);
    //     printf("请输入时段(0为谷电,1为峰电):\n");
    //     scanf("%d",&time);
    //     GateState test_gate = {
    //         .config=&GateConfig_arr[select],
    //         .front_water=front_water,
    //         .rear_water=rear_water,
    //         .period=time==0?"offpeak":"peak"
    //     };
    //     evaluate_rules(&test_gate);
    //     char buf[3][12]={"蓄水","放水","保持"};
    //     printf("闸门状态: %s\n", buf[test_gate.is_open]);
    // }
    // return 0;
    const GateConfig GateConfig_arr[4]={flood_gate_config,intake_gate_config,reservoir_A_config,reservoir_B_config};
    // 测试用例结构体
    typedef struct {
        const char* name;      // 测试名称
        int gate_type;         // 闸门类型索引
        float front;           // 闸前水位
        float rear;            // 闸后水位
        const char* period;    // 时段
        int expected_action;   // 预期动作
    } TestCase;

    // 测试用例集合
    TestCase tests[] = {
        // 泄洪闸测试
        {"泄洪闸-正常泄洪", 0, 12.0f, 7.5f, "normal", 1},
        {"泄洪闸-闸后超限", 0, 12.0f, 8.5f, "normal", 0},
        {"泄洪闸-低水位", 0, 9.0f, 6.0f, "normal", 0},

        // 进水闸测试  
        {"进水闸-安全进水", 1, 0.0f, 4.9f, "normal", 1},
        {"进水闸-超限关闭", 1, 0.0f, 5.1f, "normal", 0},
        {"进水闸-边界水位", 1, 0.0f, 5.0f, "normal", 1},

        // 水库A测试
        {"水库A-高水位放水", 2, 16.0f, 9.0f, "normal", 1},
        {"水库A-低水位蓄水", 2, 4.0f, 8.0f, "normal", 0},
        {"水库A-超安全水位", 2, 16.0f, 11.0f, "normal", 0},

        // 水库B测试
        {"水库B-峰电放水", 3, 22.0f, 11.0f, "peak", 1},
        {"水库B-峰电安全关闭", 3, 22.0f, 12.5f, "peak", 0},
        {"水库B-谷电蓄水", 3, 19.0f, 10.0f, "offpeak", 0},
        {"水库B-谷电满水放水", 3, 21.0f, 11.0f, "offpeak", 1}
    };

    // 执行测试
    int total = sizeof(tests)/sizeof(TestCase);
    int passed = 0;
    
    for(int i=0; i<total; i++){
        TestCase tc = tests[i];
        
        // 初始化闸门状态
        GateState gate = {
            .config = &GateConfig_arr[tc.gate_type],
            .front_water = tc.front,
            .rear_water = tc.rear,
            .period = tc.period
        };

        // 执行规则评估
        evaluate_rules(&gate);

        // 验证结果
        int result = (gate.is_open == tc.expected_action);
        printf("[%s] %s\t实际:%s\n", 
               result ? "通过" : "失败",
               tc.name,
               gate.is_open ? "放水" : "蓄水");
        
        passed += result;
    }

    // 输出统计
    printf("\n测试结果: %d/%d 通过 (%.1f%%)\n", 
           passed, total, (float)passed/total*100);
    
    return 0;
}